﻿using System;
using System.Diagnostics.Contracts;

namespace EuroManager.Domain.Simulator.Engine
{
    [ContractClass(typeof(MovingEntityContract))]
    public interface IMovingEntity : ITimeAware
    {
        Vector2D Location { get; }

        float X { get; }

        float Y { get; }

        Vector2D Velocity { get; }

        Vector2D Heading { get; }

        bool IsMoving { get; }

        float Speed { get; }

        float DistanceTo(Vector2D target);

        float DistanceTo(IMovingEntity entity);

        Vector2D DirectionTo(Vector2D target);

        Vector2D DirectionTo(IMovingEntity entity);

        void Turn(Vector2D target);
    }

    [ContractClassFor(typeof(IMovingEntity))]
    public abstract class MovingEntityContract : IMovingEntity
    {
        public abstract Vector2D Location { get; }

        public abstract float X { get; }

        public abstract float Y { get; }

        public abstract Vector2D Velocity { get; }

        public abstract Vector2D Heading { get; }

        public abstract bool IsMoving { get; }

        public abstract float Speed { get; }

        public abstract float DistanceTo(Vector2D target);

        public float DistanceTo(IMovingEntity entity)
        {
            Contract.Requires(entity != null);
            return 0;
        }

        public abstract Vector2D DirectionTo(Vector2D target);

        public Vector2D DirectionTo(IMovingEntity entity)
        {
            Contract.Requires(entity != null);
            return Vector2D.Zero;
        }

        public abstract void Turn(Vector2D target);
        
        public abstract void Update(float elapsedTime);
    }
}
